package ecoll.server.quiz;

import java.util.ArrayList;
import java.util.Date;

import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;

import ecoll.client.quiz.QuizUserData;
import ecoll.server.Server;
import ecoll.shared.Constant;

public class QuizRoom {

	public QuizRoom(String name, Date date, int period, int delay, int round,
			QuizQuestion question) {
		this.name = name;
		this.date = date;
		this.period = period;
		this.delay = delay;
		this.round = round;
		this.question = question;
		users = null;
	}

	// public void initialize(ArrayList<Long> files) {

	/*
	 * String backend = BackendServiceFactory.getBackendService()
	 * .getBackendAddress("quiz-backend"); TaskOptions taskOptions =
	 * TaskOptions.Builder.withUrl("/room") .method(Method.POST).header("Host",
	 * backend) .param("channel", token); Queue queue =
	 * QueueFactory.getDefaultQueue(); queue.add(taskOptions);
	 */

	public String getRoundId() {
		return name + "-" + date.getTime() + "-" + round;
	}

	public String join() {
		String user = Server.getUser();
		String channelName = name + ":" + user;
		if (QuizDatabase.putUser(name, user, channelName) == null)
			return null;

		ChannelService chService = ChannelServiceFactory.getChannelService();
		String token = chService.createChannel(channelName);
		notifyAll(Constant.Message.JOIN, user);

		if (question != null) {
			ChannelMessage message = new ChannelMessage(channelName,
					question.question);
			ChannelServiceFactory.getChannelService().sendMessage(message);
		}
		return token;
	}

	public void leave() {
		String user = Server.getUser();
		Boolean result = QuizDatabase.deleteUser(name, user);
		if (Boolean.TRUE.equals(result))
			QuizDatabase.deleteRoom(name);
		notifyAll(Constant.Message.LEAVE, user);
	}

	public Boolean answer(String answer) {
		if (answer == null)
			return false;
		String user = Server.getUser();
		notifyAll(Constant.Message.INFO, user + ": " + answer);

		if (question == null || !question.check(answer))
			return false;
		Boolean result = QuizDatabase.tryAnswer(name, user, answer);
		if (!Boolean.TRUE.equals(result))
			return result;

		notifyAll(Constant.Message.ANSWER, user + " " + question.answers);
		QuizTaskServlet.schedule(name, getRoundId(), 0, true);
		return true;
	}

	public void newQuestion() {
		Boolean result = QuizDatabase.tryAnswer(name, QuizDatabase.UNANSWERED,
				null);
		if (result == null)
			return;
		if (result == true)
			notifyAll(Constant.Message.NOANSWER, "" + question.answers);
		for (int i = delay; i > 0; --i) {
			notifyAll(Constant.Message.COUNT, "" + i);
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
		}
		question = QuizDatabase.newQuestion(name);
		users = QuizDatabase.getUsers(name, false);
		notifyAll(Constant.Message.QUESTION, question.question);
		++round;
		QuizTaskServlet.schedule(name, getRoundId(), period, false);
	}

	public String getQuestion() {
		if (question == null)
			return null;
		return question.question;
	}

	public ArrayList<QuizUserData> getRanking() {
		return QuizDatabase.getUsers(name, true);
	}

	private void notifyAll(Constant.Message type, String message) {
		if (users == null)
			users = QuizDatabase.getUsers(name, false);

		ChannelService channelService = ChannelServiceFactory
				.getChannelService();
		for (QuizUserData data : users) {
			ChannelMessage channelMessage = new ChannelMessage(
					data.getChannel(), type + " " + message);
			channelService.sendMessage(channelMessage);
		}
	}

	private String name;
	private Date date;
	private ArrayList<QuizUserData> users;
	private int period;
	private int delay;
	private int round;
	private QuizQuestion question;
}
